import sys

import pygame

from bullet import Bullet
from Alien import Alien
from time import sleep

def check_keydown_events(event,ai_settings,screen,ship,bullets):
    """ 响应按键按下 """
    if event.key == pygame.K_RIGHT:
        # 使能飞船右移标志
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        # 使能飞船左移标志
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:       
        fire_bullet(ai_settings, bullets, screen, ship)
    elif event.key == pygame.K_q:
        sys.exit()

def check_keyup_events(event, ship):
    """ 响应按键弹起 """
    if event.key == pygame.K_RIGHT:
        # 失能飞船右移标志
        ship.moving_right = False
    elif event.key == pygame.K_LEFT:
        # 失能飞船左移标志
        ship.moving_left = False


def check_play_button(ai_settings, screen, ship, aliens,bullets,
                      stats, play_button, mouse_x, mouse_y,sb):
    """在玩家单击Play按钮时开始新游戏""" 
    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
        pygame.mouse.set_visible(False)
        stats.reset_stats()
        # 重置记分牌图像
        sb.prep_score()
        sb.prep_high_score()
        sb.prep_level()
        sb.prep_ships()
        # 重置游戏设置
        ai_settings.initialize_dynamic_settings()
        stats.game_active = True
        # 清空外星人列表和子弹列表
        aliens.empty()
        bullets.empty()
        # 创建一群新的外星人，并将飞船放到屏幕底端中央
        create_fleet(ai_settings, screen, ship, aliens)
        ship.center_ship()

def check_event(ai_settings, screen, ship, aliens,bullets,stats, play_button,sb):
    """ 监视鼠标和键盘事件 """
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event,ai_settings,screen,ship,bullets)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, ship)
        elif event.type == pygame.MOUSEBUTTONDOWN: 
            mouse_x, mouse_y = pygame.mouse.get_pos() 
            check_play_button(ai_settings, screen, ship, aliens,bullets,
                      stats, play_button, mouse_x, mouse_y,sb)

def update_screen(ai_settings,screen,ship,bullets,aliens,play_button,stats,sb):
    """ 更新屏幕上的图像，并切换到新屏幕 """
    # 设置背景色
    screen.fill(ai_settings.bg_color)

    # 绘制计分板
    sb.show_score()

    # 绘制飞船
    ship.blitme()

    # 绘制外星人群
    aliens.draw(screen)

    # 在飞船和外星人后绘制子弹
    for bullet in bullets.sprites():
        bullet.draw_bullet()

    # 绘制按钮
    if not stats.game_active:
        play_button.draw_button()      
        
    # 让最近绘制的屏幕可见
    pygame.display.flip()


def check_high_score(stats, sb):
    """检查是否诞生了新的最高得分"""
    if stats.score > stats.high_score:
        stats.high_score = stats.score
        sb.prep_high_score()

def check_bullet_alien_collisions(ai_settings, aliens, bullets, screen, ship,sb,stats):
    ''' 检查是否有子弹击中了外星人 '''
    collisions = pygame.sprite.groupcollide(bullets, aliens, False, True)
    
    if collisions:
        for aliens in collisions.values():
            stats.score += ai_settings.alien_points * len(aliens)
            sb.prep_score()
        check_high_score(stats, sb)

    if len(aliens) == 0:
        # 删除现有的子弹并新建一群外星人
        bullets.empty()
        create_fleet(ai_settings,screen,ship,aliens)
        ai_settings.increase_speed()
        # 提高等级 
        stats.level += 1
        sb.prep_level()

def update_bullets(ai_settings,screen,ship,aliens,bullets,sb,stats):
    ''' 管理所有子弹对象 '''
    # 限制子弹数量
    for bullet in bullets.copy():
        if bullet.rect.bottom <= 0:
            bullets.remove(bullet)
    # 更新有效子弹位置
    bullets.update()

    # 检查是否有子弹击中了外星人
    # 如果是这样，就删除相应的子弹和外星人
    check_bullet_alien_collisions(ai_settings, aliens, bullets, screen, ship,sb,stats)
    
def fire_bullet(ai_settings, bullets, screen, ship):
    ''' 发射一颗子弹 '''
    # 限制子弹数量,创建一颗子弹，并将其加入到编组bullets中
    if len(bullets) < ai_settings.bullets_allowed:
        new_bullet = Bullet(ai_settings,screen,ship)
        bullets.add(new_bullet)


def get_number_aliens_x(ai_settings, alien_width):
    ''' 获取在屏幕一行中可以存在多少个外星人 '''
    available_space_x = ai_settings.screen_width - alien_width * 2
    number_aliens_x = int(available_space_x /(alien_width * 2))
    return number_aliens_x

def get_number_rows(ai_settings,ship_height,alien_height):
    ''' 计算屏幕能存在多少行外星人 '''
    available_space_y = (ai_settings.screen_height -
                        (3 * alien_height) - ship_height)
    number_rows = int(available_space_y / (2 * alien_height))
    return number_rows

def creat_alien(ai_settings,screen,aliens,alien_number,row_number):
    ''' 创建外星人,设定位置，加入组 '''
    alien = Alien(ai_settings,screen)
    alien_width = alien.rect.width
    alien.x = alien_width + alien_width * alien_number * 2
    alien.rect.x = alien.x  
    alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
    aliens.add(alien)

def create_fleet(ai_settings,screen,ship,aliens):
    ''' 绘制外星人群 '''
    alien = Alien(ai_settings,screen)
    number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
    number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)
    for r in range(number_rows):
        for c in range(number_aliens_x):
            creat_alien(ai_settings,screen,aliens,c,r)
        

def change_fleet_direction(ai_settings, aliens):
    """将整群外星人下移，并改变它们的方向"""
    for alien in aliens.sprites():
        alien.rect.y += ai_settings.fleet_drop_speed

    ai_settings.fleet_direction *= -1

def check_fleet_edges(ai_settings, aliens):
    """有外星人到达边缘时采取相应的措施"""
    for alien in aliens.sprites():
        if alien.check_edges():
            change_fleet_direction(ai_settings, aliens)
            break 

def ship_hit(ai_settings, stats, screen, ship, aliens, bullets,sb):
    """响应被外星人撞到的飞船"""
    # 将ships_left减1
    stats.ships_left -= 1
    # 更新记分牌
    sb.prep_ships()

    if stats.ships_left <= 0:
        stats.game_active = False
        pygame.mouse.set_visible(True)
    else:
        stats.game_active = True
        # 清空外星人列表和子弹列表
        aliens.empty()
        bullets.empty()
        # 创建一群新的外星人，并将飞船放到屏幕底端中央
        create_fleet(ai_settings, screen, ship, aliens)
        ship.center_ship()
        # 暂停
        sleep(0.5)
     
    
def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets,sb):
    """检查是否有外星人到达了屏幕底端"""
    screen_rect = screen.get_rect()
    for alien in aliens.sprites():
        if alien.rect.bottom >= screen_rect.bottom:
            # 像飞船被撞到一样进行处理
            ship_hit(ai_settings, stats, screen, ship, aliens, bullets,sb)
            break


def update_aliens(ai_settings,ship,aliens,stats, bullets, screen,sb):
    """更新外星人群中所有外星人的位置"""
    check_fleet_edges(ai_settings, aliens)
    aliens.update()

    # 外星人到达屏幕底部
    check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets,sb)

    # 外星人与飞船相撞
    if pygame.sprite.spritecollideany(ship, aliens):
        print('ship hit')
        ship_hit(ai_settings, stats, screen, ship, aliens, bullets,sb)

